﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PServiceBus.Core.Interface;
using System.Collections;
using PServiceBus.Core.Runtime.Topics;
using PServiceBus.Core.Runtime.Extensions;
using PServiceBus.Core.Runtime.Messages;
using PServiceBus.Core.Runtime;
using PServiceBus.Core.Runtime.Transports;
using PServiceBus.Core.Runtime.Configuration;
using System.Threading.Tasks;

namespace PServiceBus.Core.Manager {
    /// <summary>
    /// Static class for generating TopicMessage object from ITopic
    /// </summary>
    public class TopicMessageManager {
        /// <summary>
        /// Generate and add the generated TopicMessage to the current underlying data store [IObjectManager]
        /// </summary>
        /// <param name="topic">The topic.</param>
        /// <param name="parameters">The parameter.</param>
        public static void Add(ITopic topic, List<Dictionary<string, object>> parameters) {
            if (topic == null) return;
            TopicMessages.Attach(Create(topic, parameters, ConfigurationProvider.ServiceBusConfig.DefaultMessageExpiresIn, null));
        }
        /// <summary>
        /// Add a list of TopicMessage into the current underlying data store [IObjectManager]
        /// </summary>
        /// <param name="topicMessages">The topic messages.</param>
        public static void Add(IEnumerable<TopicMessage> topicMessages) {
            TopicMessages.AttachMany(topicMessages);
        }

        /// <summary>
        /// Add a message to the underlying data store [IObjectManager]
        /// </summary>
        /// <param name="topicMessage"></param>
        public static void Add(TopicMessage topicMessage) {
            TopicMessages.Attach(topicMessage);
        }

        private static IObjectManager<TopicMessage> _topicMessages = null;
        private static IObjectManager<TopicMessage> TopicMessages {
            get {
                if (_topicMessages == null) {
                    var distributorEnabled = ConfigurationProvider.DistributorConfig.Enabled;
                    _topicMessages = PServiceBus.Core.Manager.ObjectManager<TopicMessage>.Create(
                        distributorEnabled ? ConfigurationProvider.DistributorConfig.Address : ConfigurationProvider.Address,
                        distributorEnabled ? ConfigurationProvider.DistributorConfig.AddressID : null);
                }
                return _topicMessages;
            }
        }

        /// <summary>
        /// Generate a new TopicMessage from ITopic and merge addition information into TopicMessage Parameter
        /// </summary>
        /// <param name="topic">The topic.</param>
        /// <param name="parameters">The addition parameter.</param>
        /// <returns></returns>
        public static TopicMessage Create(ITopic topic, List<Dictionary<string, object>> parameters, TimeSpan? expiresIn,
            Dictionary<string, string> headers) {
            return new TopicMessage()
            {
                TopicID = topic.ID,
                CreateDate = DateTime.UtcNow,
                ID = Guid.NewGuid(),
                Message = new TransportMessage() { 
                    TopicName = topic.Name,
                    Headers = headers ?? new Dictionary<string,string>(),
                    Parameters = parameters ?? new List<Dictionary<string, object>>(),
                    CreateDate = DateTime.UtcNow,
                    ExpiresIn = expiresIn ?? (ConfigurationProvider.ServiceBusConfig.DefaultMessageExpiresIn == TimeSpan.Zero ? TimeSpan.FromDays(30) :
                    ConfigurationProvider.ServiceBusConfig.DefaultMessageExpiresIn)
                }
            };
        }
    }
}
